websocket系列:基于spring

您所在的位置:网站首页 springboot websocket client websocket系列:基于spring

websocket系列:基于spring

#websocket系列:基于spring| 来源: 网络整理| 查看: 265

前言

2021春节后第一篇文章,承接之前继续完成websocket系列,本篇主要是介绍怎么基于spring-boot-starter-websocket来实现websocket。

一、项目结构

在这里插入图片描述

二、具体说明 1.引入maven依赖 org.springframework.boot spring-boot-starter-websocket org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test 2.实现WebSocketConfigurer配置类 @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Autowired private MyWsHandler myWsHandler; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry .addHandler(myWsHandler, "myWs") //允许跨域 .setAllowedOrigins("*"); } }

说明: 通过实现WebSocketConfigurer配置类,重写registerWebSocketHandlers方法,注册自定义的WebSocketHandler的实现类MyWsHandler,并指定类对应的websocket访问的ServerEndpoint为/myWs。 通过@EnableWebSocket注解,启动spring-boot-starter-websocket的自动化配置。

3.自定义WebSocketHandler /** * ws消息处理类 */ @Component @Slf4j public class MyWsHandler extends AbstractWebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { log.info("建立ws连接"); WsSessionManager.add(session.getId(),session); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { log.info("发送文本消息"); // 获得客户端传来的消息 String payload = message.getPayload(); log.info("server 接收到消息 " + payload); session.sendMessage(new TextMessage("server 发送给的消息 " + payload + ",发送时间:" + LocalDateTime.now().toString())); } @Override protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception { log.info("发送二进制消息"); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { log.error("异常处理"); WsSessionManager.removeAndClose(session.getId()); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { log.info("关闭ws连接"); WsSessionManager.removeAndClose(session.getId()); } }

说明: 通过继承 AbstractWebSocketHandler 类并覆盖相应方法,可以对 websocket 的事件进行处理,这里可以同原生注解的那几个注解连起来看 afterConnectionEstablished 方法是在 socket 连接成功后被触发,同原生注解里的 @OnOpen 功能。 afterConnectionClosed方法是在 socket 连接关闭后被触发,同原生注解里的 @OnClose 功能。 handleTextMessage方法是在客户端发送普通文件信息时触发,同原生注解里的 @OnMessage 功能。 handleBinaryMessage 方法是在客户端发送二进制信息时触发,同原生注解里的 @OnMessage 功能。 handleTransportError方法同原生注解里的@OnError。

除了继承AbstractWebSocketHandler类外,还有以下WebSocketHandler可供选择。 AbstractWebSocketHandler可以同时支持普通文本和二进制的消息处理。 BinaryWebSocketHandler只支持二进制消息。 TextWebSocketHandler只支持普通文本消息。 在这里插入图片描述

4.定时消息推送MessageJob /** * 消息生成job */ @Slf4j @Component public class MessageJob { @Autowired WsService wsService; /** * 每5s发送 */ @Scheduled(cron = "0/5 * * * * *") public void run(){ try { wsService.broadcastMsg("自动生成消息 " + LocalDateTime.now().toString()); } catch (IOException e) { e.printStackTrace(); } } } 5.消息推送服务类WsService /** * ws操作相关服务 */ @Service @Slf4j public class WsService { /** * 发送消息 * @param session * @param text * @return * @throws IOException */ public void sendMsg(WebSocketSession session, String text) throws IOException { session.sendMessage(new TextMessage(text)); } /** * 广播消息 * @param text * @return * @throws IOException */ public void broadcastMsg(String text) throws IOException { for (WebSocketSession session: WsSessionManager.SESSION_POOL.values()) { session.sendMessage(new TextMessage(text)); } } } 6.Session管理类WsSessionManager @Slf4j public class WsSessionManager { /** * 保存连接 session 的地方 */ public static ConcurrentHashMap SESSION_POOL = new ConcurrentHashMap(); /** * 添加 session * * @param key */ public static void add(String key, WebSocketSession session) { // 添加 session SESSION_POOL.put(key, session); } /** * 删除 session,会返回删除的 session * * @param key * @return */ public static WebSocketSession remove(String key) { // 删除 session return SESSION_POOL.remove(key); } /** * 删除并同步关闭连接 * * @param key */ public static void removeAndClose(String key) { WebSocketSession session = remove(key); if (session != null) { try { // 关闭连接 session.close(); } catch (IOException e) { // todo: 关闭出现异常处理 e.printStackTrace(); } } } /** * 获得 session * * @param key * @return */ public static WebSocketSession get(String key) { // 获得 session return SESSION_POOL.get(key); } } 7.启动类SpringWsApplication @SpringBootApplication @EnableScheduling public class SpringWsApplication { public static void main(String[] args) { SpringApplication.run(SpringWsApplication.class, args); } } 8.首页index.html

发现很多小伙伴不知道调用WebSocket的前端页面怎么写,这里重新补充一下。

My WebSocket Send Close let ws = null; //判断当前浏览器是否支持WebSocket if ('WebSocket' in window) { ws = new WebSocket("ws://localhost:8333/myWs"); } else { alert('当前浏览器 Not support websocket') } //连接发生错误的回调方法 ws.onerror = function () { setMessageInnerHTML("WebSocket连接发生错误"); }; //连接成功建立的回调方法 ws.onopen = function(event) { console.log("ws调用连接成功回调方法") //ws.send("") } //接收到消息的回调方法 ws.onmessage = function(message) { console.log("接收消息:" + message.data); if (typeof(message.data) == 'string') { setMessageInnerHTML(message.data); } } //ws连接断开的回调方法 ws.onclose = function(e) { console.log("ws连接断开") //console.log(e) setMessageInnerHTML("ws close"); } //将消息显示在网页上 function setMessageInnerHTML(innerHTML) { console.log(innerHTML) document.getElementById('message').innerHTML += '接收的消息:' + innerHTML + ''; } //关闭连接 function closeWebSocket() { ws.close(); } //发送消息 function send(msg) { if(!msg){ msg = document.getElementById('text').value; document.getElementById('message').innerHTML += "发送的消息:" + msg + ''; ws.send(msg); } } 9.测试

在这里插入图片描述

总结

基于spring-boot-starter-websocket实现也非常简单,主要是3个实现步骤: 1.通过继承AbstractWebSocketHandler自定义WebSocketHandler,重写afterConnectionEstablished、handleTextMessage、handleBinaryMessage、handleTransportError、afterConnectionClosed等方法,都能和jdk的原生websocket注解对应上。 2.通过实现WebSocketConfigurer进行WebSocket的相关配置,利用WebSocketHandlerRegistry注册自定义的WebSocketHandler。 3.消息的发送主要是通过WebSocketSession来实现。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3